# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: site-packages\ntlm_auth\des_c.py
import six
from ntlm_auth.U32 import U32
from ntlm_auth.des_data import des_SPtrans, des_skb


def c2l(c):
    """char[4] to unsigned long"""
    l = U32(c[0])
    l = l | U32(c[1]) << 8
    l = l | U32(c[2]) << 16
    l = l | U32(c[3]) << 24
    return l


def l2c(l):
    """unsigned long to char[4]"""
    c = []
    c.append(int(l & U32(255)))
    c.append(int(l >> 8 & U32(255)))
    c.append(int(l >> 16 & U32(255)))
    c.append(int(l >> 24 & U32(255)))
    return c


def D_ENCRYPT(tup, u, t, s):
    L, R, S = tup
    u = R ^ s[S]
    t = R ^ s[S + 1]
    t = (t >> 4) + (t << 28)
    L = L ^ (
        des_SPtrans[1][int(t & U32(63))]
        | des_SPtrans[3][int(t >> 8 & U32(63))]
        | des_SPtrans[5][int(t >> 16 & U32(63))]
        | des_SPtrans[7][int(t >> 24 & U32(63))]
        | des_SPtrans[0][int(u & U32(63))]
        | des_SPtrans[2][int(u >> 8 & U32(63))]
        | des_SPtrans[4][int(u >> 16 & U32(63))]
        | des_SPtrans[6][int(u >> 24 & U32(63))]
    )
    return ((L, R, S), u, t, s)


def PERM_OP(tup, n, m):
    """tup - (a, b, t)"""
    a, b, t = tup
    t = (a >> n ^ b) & m
    b = b ^ t
    a = a ^ t << n
    return (a, b, t)


def HPERM_OP(tup, n, m):
    """tup - (a, t)"""
    a, t = tup
    t = (a << 16 - n ^ a) & m
    a = a ^ t ^ t >> 16 - n
    return (a, t)


shifts2 = [0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0]


class DES:
    KeySched = None

    def __init__(self, key_str):
        self.KeySched = des_set_key(key_str)

    def decrypt(self, str):
        block = []
        for i in six.iterbytes(str):
            block.append(i)

        block = des_ecb_encrypt(block, self.KeySched, 0)
        res = b""
        for i in block:
            res = res + six.int2byte(i)

        return res

    def encrypt(self, plaintext):
        block = []
        for i in plaintext:
            block.append(i)

        block = des_ecb_encrypt(block, self.KeySched, 1)
        res = b""
        for i in block:
            res += six.int2byte(i)

        return res


def des_encript(input, ks, encrypt):
    l = input[0]
    r = input[1]
    t = U32(0)
    u = U32(0)
    r, l, t = PERM_OP((r, l, t), 4, U32(252645135))
    l, r, t = PERM_OP((l, r, t), 16, U32(65535))
    r, l, t = PERM_OP((r, l, t), 2, U32(858993459))
    l, r, t = PERM_OP((l, r, t), 8, U32(16711935))
    r, l, t = PERM_OP((r, l, t), 1, U32(1431655765))
    t = r << 1 | r >> 31
    r = l << 1 | l >> 31
    l = t
    s = ks
    if encrypt:
        for i in range(0, 32, 4):
            rtup, u, t, s = D_ENCRYPT((l, r, i + 0), u, t, s)
            l = rtup[0]
            r = rtup[1]
            rtup, u, t, s = D_ENCRYPT((r, l, i + 2), u, t, s)
            r = rtup[0]
            l = rtup[1]

    else:
        for i in range(30, 0, -4):
            rtup, u, t, s = D_ENCRYPT((l, r, i - 0), u, t, s)
            l = rtup[0]
            r = rtup[1]
            rtup, u, t, s = D_ENCRYPT((r, l, i - 2), u, t, s)
            r = rtup[0]
            l = rtup[1]

    l = l >> 1 | l << 31
    r = r >> 1 | r << 31
    r, l, t = PERM_OP((r, l, t), 1, U32(1431655765))
    l, r, t = PERM_OP((l, r, t), 8, U32(16711935))
    r, l, t = PERM_OP((r, l, t), 2, U32(858993459))
    l, r, t = PERM_OP((l, r, t), 16, U32(65535))
    r, l, t = PERM_OP((r, l, t), 4, U32(252645135))
    output = [l]
    output.append(r)
    l, r, t, u = (U32(0), U32(0), U32(0), U32(0))
    return output


def des_ecb_encrypt(input, ks, encrypt):
    l0 = c2l(input[0:4])
    l1 = c2l(input[4:8])
    ll = [l0]
    ll.append(l1)
    ll = des_encript(ll, ks, encrypt)
    l0 = ll[0]
    l1 = ll[1]
    output = l2c(l0)
    output = output + l2c(l1)
    l0, l1, ll[0], ll[1] = (U32(0), U32(0), U32(0), U32(0))
    return output


def des_set_key(key):
    k = []
    c = c2l(key[0:4])
    d = c2l(key[4:8])
    t = U32(0)
    d, c, t = PERM_OP((d, c, t), 4, U32(252645135))
    c, t = HPERM_OP((c, t), -2, U32(3435921408))
    d, t = HPERM_OP((d, t), -2, U32(3435921408))
    d, c, t = PERM_OP((d, c, t), 1, U32(1431655765))
    c, d, t = PERM_OP((c, d, t), 8, U32(16711935))
    d, c, t = PERM_OP((d, c, t), 1, U32(1431655765))
    d = (
        (d & U32(255)) << 16
        | d & U32(65280)
        | (d & U32(16711680)) >> 16
        | (c & U32(4026531840)) >> 4
    )
    c = c & U32(268435455)
    for i in range(16):
        if shifts2[i]:
            c = c >> 2 | c << 26
            d = d >> 2 | d << 26
        else:
            c = c >> 1 | c << 27
            d = d >> 1 | d << 27
        c = c & U32(268435455)
        d = d & U32(268435455)
        s = (
            des_skb[0][int(c & U32(63))]
            | des_skb[1][int(c >> 6 & U32(3) | c >> 7 & U32(60))]
            | des_skb[2][int(c >> 13 & U32(15) | c >> 14 & U32(48))]
            | des_skb[3][int(c >> 20 & U32(1) | c >> 21 & U32(6) | c >> 22 & U32(56))]
        )
        t = (
            des_skb[4][int(d & U32(63))]
            | des_skb[5][int(d >> 7 & U32(3) | d >> 8 & U32(60))]
            | des_skb[6][int(d >> 15 & U32(63))]
            | des_skb[7][int(d >> 21 & U32(15) | d >> 22 & U32(48))]
        )
        k.append((t << 16 | s & U32(65535)) & U32(4294967295))
        s = s >> 16 | t & U32(4294901760)
        s = s << 4 | s >> 28
        k.append(s & U32(4294967295))

    schedule = k
    return schedule
